#include <QtGlobal>
#include <QDebug>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
#include <QFile>
#include <QCoreApplication>

#include "cengine.h"

const QString KDatabaseType("QSQLITE");

//#define MEM_DB
#ifdef MEM_DB
const QString KDatabaseName(":memory:");
#else
const QString KDatabaseName("Cooking.db");
#endif

CEngine::CEngine()
{
    initDb();
    //    m_cuisineModel = new CCuisineModel(this);
    //    m_recipeModel = new CRecipeModel(this);
}

CEngine::~CEngine()
{

}

bool CEngine::createCuisineTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableCuisine + "(");
    sql->append(KCuisineId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KCuisineParentId + KTypeInt);
    sql->append(KComma + KCuisineName + KTypeStr);
    sql->append(KComma + KCuisineDescription + KTypeStr);
    sql->append(KComma + KCuisineRegionId + KTypeInt);
    sql->append(KComma + KCuisinePicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createRecipeTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableRecipe + "(");
    sql->append(KRecipeId + KTypeInt + KPrimaryKey + KAutoIncrement);
    //    sql->append(KComma + KRecipeCuisineId + KTypeInt);
    sql->append(KComma + KRecipeName + KTypeStr);
    sql->append(KComma + KRecipeRepresentative + KTypeInt);
    sql->append(KComma + KRecipeDescription + KTypeStr);
    sql->append(KComma + KRecipeFlavourId + KTypeInt);
    sql->append(KComma + KRecipeTechniqueId + KTypeInt);
    sql->append(KComma + KRecipePreparingTime + KTypeInt);
    sql->append(KComma + KRecipeCookingTime + KTypeInt);
    sql->append(KComma + KRecipeDifficulty + KTypeInt);
    sql->append(KComma + KRecipeDishTypeId + KTypeInt);
    sql->append(KComma + KRecipeFoodTypeId + KTypeInt);
    sql->append(KComma + KRecipeServe + KTypeInt);
    sql->append(KComma + KRecipePicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createCuisineRecipeTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableCuisineRecipe + "(");
    sql->append(KCuisineRecipeId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KCuisineRecipeCuisineId + KTypeInt);
    sql->append(KComma + KCuisineRecipeRecipeId + KTypeInt);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createRegionTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableRegion + "(");
    sql->append(KRegionId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KRegionParentId + KTypeInt);
    sql->append(KComma + KRegionName + KTypeStr);
    sql->append(KComma + KRegionDescription + KTypeStr);
    sql->append(KComma + KRegionPicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createFlavourTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableFlavour + "(");
    sql->append(KFlavourId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KFlavourName + KTypeStr);
    sql->append(KComma + KFlavourDescription + KTypeStr);
    sql->append(KComma + KFlavourPicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createIngredientTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableIngredient + "(");
    sql->append(KIngredientId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KIngredientName + KTypeStr);
    sql->append(KComma + KIngredientDescription + KTypeStr);
    sql->append(KComma + KIngredientCategoryIdentify + KTypeInt);
    sql->append(KComma + KIngredientPicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createTechniqueTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableTechnique + "(");
    sql->append(KTechniqueId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KTechniqueParentId + KTypeInt);
    sql->append(KComma + KTechniqueName + KTypeStr);
    sql->append(KComma + KTechniqueDescription + KTypeStr);
    sql->append(KComma + KTechniquePicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createDishTypeTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableDishType + "(");
    sql->append(KDishTypeId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KDishTypeParentId + KTypeInt);
    sql->append(KComma + KDishTypeName + KTypeStr);
    sql->append(KComma + KDishTypeDescription + KTypeStr);
    sql->append(KComma + KDishTypePicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createFoodTypeTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableFoodType + "(");
    sql->append(KFoodTypeId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KFoodTypeParentId + KTypeInt);
    sql->append(KComma + KFoodTypeName + KTypeStr);
    sql->append(KComma + KFoodTypeDescription + KTypeStr);
    sql->append(KComma + KFoodTypePicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createMethodTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableMethod + "(");
    sql->append(KMethodId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KMethodRecipeId + KTypeInt);
    sql->append(KComma + KMethodStep + KTypeInt);
    sql->append(KComma + KMethodDescription + KTypeStr);
    sql->append(KComma + KMethodCostTime + KTypeInt);
    sql->append(KComma + KMethodPicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createRecipeIngredientTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableRecipeIngredient + "(");
    sql->append(KRecipeIngredientId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KRecipeIngredientRecipeId + KTypeInt);
    sql->append(KComma + KRecipeIngredientIngredientId + KTypeInt);
    sql->append(KComma + KRecipeIngredientQuantity + KTypeDouble);
    sql->append(KComma + KRecipeIngredientUnitTypeId + KTypeInt);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createUnitTypeTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableUnitType + "(");
    sql->append(KUnitTypeId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KUnitTypeName + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

//bool CEngine::createCategoryTable() {
//    QString *sql = new QString();
//    sql->append(KCreateTable + KTableCategory + "(");
//    sql->append(KCategoryId + KTypeInt + KPrimaryKey + KAutoIncrement);
//    sql->append(KComma + KCategoryName + KTypeStr);
//    sql->append(KComma + KCategoryDescription + KTypeStr);
//    sql->append(KComma + KCategoryPicture + KTypeStr);
//    sql->append(+")");
//    bool ret = createTable(*sql);
//    delete sql;
//    return ret;
//}

bool CEngine::createNutritionTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableNutrition + "(");
    sql->append(KNutritionId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KNutritionName + KTypeStr);
    sql->append(KComma + KNutritionDescription + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createIngredientNutritionTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableIngredientNutrition + "(");
    sql->append(KIngredientNutritionId + KTypeInt + KPrimaryKey+ KAutoIncrement);
    sql->append(KComma + KIngredientNutritionNutritionId + KTypeInt);
    sql->append(KComma + KIngredientNutritionIngredientId + KTypeInt);
    sql->append(KComma + KIngredientNutritionQuantity + KTypeDouble);
    sql->append(KComma + KIngredientNutritionUnitType + KTypeInt);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createNutritionConsumeTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableNutritionConsume + "(");
    sql->append(KNutritionConsumeId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KNutritionConsumeName + KTypeStr);
    sql->append(KComma + KNutritionConsumeDescription + KTypeStr);
    sql->append(KComma + KNutritionConsumePicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createConsumeNutritionTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableConsumeNutrition + "(");
    sql->append(KConsumeNutritionId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KConsumeNutritionConsumeId + KTypeInt);
    sql->append(KComma + KConsumeNutritionNutritionid + KTypeInt);
    sql->append(KComma + KConsumeNutritionQuantity + KTypeDouble);
    sql->append(KComma + KConsumeNutritionUnitTypeId + KTypeInt);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createMealTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableMeal + "(");
    sql->append(KMealId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KMealName + KTypeStr);
    sql->append(KComma + KMealDescription + KTypeStr);
    sql->append(KComma + KMealScheduleTime + KTypeInt);
    sql->append(KComma + KMealStatus + KTypeInt);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}


bool CEngine::createMealRecipeTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableMealRecipe + "(");
    sql->append(KMealRecipeId + KTypeInt + KPrimaryKey + KAutoIncrement);
    sql->append(KComma + KMealRecipeMealId + KTypeInt);
    sql->append(KComma + KMealRecipeRecipeId + KTypeInt);
    sql->append(KComma + KMealRecipeStatus + KTypeInt);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createTipsTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableTip + "(");
    sql->append(KTipId + KTypeInt + KPrimaryKey  + KAutoIncrement);
    sql->append(KComma + KTipRecipeId + KTypeInt);
    sql->append(KComma + KTipNumber + KTypeInt);
    sql->append(KComma + KTipDescription + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createIngredientCategoryTable() {
    QString *sql = new QString();
    sql->append(KCreateTable + KTableIngredientCategory + "(");
    sql->append(KIngredientCategoryId + KTypeInt + KPrimaryKey  + KAutoIncrement);
    sql->append(KComma + KIngredientCategoryName + KTypeStr);
    sql->append(KComma + KIngredientCategoryDescription + KTypeStr);
    sql->append(KComma + KIngredientCategoryPicture + KTypeStr);
    sql->append(+")");
    bool ret = createTable(*sql);
    delete sql;
    return ret;
}

bool CEngine::createTable(QString &sql) {
    QSqlQuery query;
    bool result = query.exec(sql);
    qDebug()<<"result:"<<result<<"CreateTable:"<<sql;
    return result;
}

int CEngine::initDb()
{
    QSqlDatabase db = QSqlDatabase::addDatabase(KDatabaseType);
    db.setDatabaseName(DatabaseName());

    // Call exists before open the db
    bool exist = QFile::exists(DatabaseName());
    if (!db.open()) {
        qDebug()<<tr("Cannot open database")
               <<tr("Unable to establish a database connection.\n"
                    "This example needs SQLite support. Please read "
                    "the Qt SQL driver documentation for information how "
                    "to build it.\n\n"
                    "Click Cancel to exit.");
        return -1;
    }

    if(!exist)
    {
        createCuisineTable();
        createRecipeTable();
        createRegionTable();
        createFlavourTable();
        createIngredientTable();
        createTechniqueTable();
        createDishTypeTable();
        createFoodTypeTable();
        createMethodTable();
        createRecipeIngredientTable();
        createUnitTypeTable();
        createCuisineRecipeTable();
        createNutritionTable();
        createIngredientNutritionTable();
        createNutritionConsumeTable();
        createConsumeNutritionTable();
        createMealTable();
        createMealRecipeTable();
        createTipsTable();
        createIngredientCategoryTable();
        addDummyData();
    }

    return 0;
}
void CEngine::addDummyData() {
    CRegion* region = new CRegion();
    //    region->setId(1);
    region->setName("中国");
    region->setParentId(-1);
    //    region->setDescription("test");
    region->setPicture("China.png");
    int chinaRegionId = addRegion(region);
    qDebug()<<"chinaRegionId:"<<chinaRegionId;
    region->setName("法国");
    region->setParentId(-1);
    region->setPicture("France.png");
    int franceRegionId = addRegion(region);
    qDebug()<<"franceRegionId:"<<franceRegionId;
    region->setName("意大利");
    region->setParentId(-1);
    region->setPicture("Italy.png");
    int italyRegionId = addRegion(region);
    qDebug()<<"italyRegionId:"<<italyRegionId;
    region->setName("日本");
    region->setParentId(-1);
    region->setPicture("Japan.png");
    int japanRegionId = addRegion(region);
    qDebug()<<"japanRegionId:"<<japanRegionId;

    CCuisine * cuisine = new CCuisine();
    cuisine->setName("中国");
    cuisine->setParentId(-1);
    cuisine->setDescription("中国菜與中华飲食文化，在日本和韓國稱爲中華料理或中國料理，"
                            "歐美稱之爲唐餐，是中国文化的组成部分，深远的影响了东亚地区的飲食文化。"
                            "菜谱来源于中国各个地区和民族的菜肴。中国菜的特点被总结为：色、香、味、意、形。"
                            "被称为国菜五品。按烹饪特点分又可分为：选料、刀工、火候和调味四个方面。"
                            "但不论如何，中国菜只是一个统称，各个地方差异极大。代表菜系有鲁菜、淮扬菜、川菜、粤菜。");
    cuisine->setRegionId(chinaRegionId);
    cuisine->setPicture("Chinese.jpg");
    int chinaCuisineId = addCuisine(cuisine);

    cuisine->setName("川菜");
    cuisine->setParentId(chinaCuisineId);
    cuisine->setDescription("四川菜历史悠久，在国内外都享有很高的声誉。"
                            "特点是突出麻、辣、香、鲜、油大、味厚，重用“三椒”"
                            "(辣椒、花椒、胡椒)和鲜姜。调味方法有干烧、鱼香、怪味、"
                            "椒麻、红油、姜汁、糖醋、荔枝、蒜泥等复合味型，形成了川菜"
                            "的特殊风味，享有“一菜一格，百菜百味”的美誉。");
    cuisine->setRegionId(chinaRegionId);
    cuisine->setPicture("Chinese.jpg");
    int sichuanCuisineId = addCuisine(cuisine);
    qDebug()<<"sichuanCuisineId:"<<sichuanCuisineId;

    cuisine->setName("鲁菜");
    cuisine->setParentId(chinaCuisineId);
    cuisine->setDescription("山东菜简称鲁菜，有北方代表菜之称，"
                            "也是黄河流域烹饪文化的代表，是中国著名的八大菜系之一"
                            "，它对北京、天津、华北、东北地区烹调技术的发展影响很大。"
                            "原料多选畜禽、海产、蔬菜,善用爆、熘、扒、烤、锅、拔丝、"
                            "蜜汁等烹调方法，偏重于酱、葱、蒜调味，善用清汤、奶汤增鲜，"
                            "口味咸鲜。");
    cuisine->setRegionId(chinaRegionId);
    cuisine->setPicture("Chinese.jpg");
    int shandongCuisineId = addCuisine(cuisine);

    cuisine->setName("粤菜");
    cuisine->setParentId(chinaCuisineId);
    cuisine->setDescription("广东菜，简称粤菜，是我国四大菜系之一，"
                            "有“食在广州”的美誉。广东地处亚热带，濒临南海，四季常青，"
                            "物产丰富，山珍海味无所不有，蔬果时鲜四季不同，清人竹"
                            "枝词曰：“响螺脆不及至鲜。");
    cuisine->setRegionId(chinaRegionId);
    cuisine->setPicture("Chinese.jpg");
    int guangdongCuisineId = addCuisine(cuisine);

    cuisine->setName("徽菜");
    cuisine->setParentId(chinaCuisineId);
    cuisine->setDescription("徽皖风味，指安徽菜，简称徽菜，"
                            "是我国八大菜系之一。徽菜的形成与发展，"
                            "是和安徽的地理环境、经济物产、风尚习俗密切相关联的。");
    cuisine->setRegionId(chinaRegionId);
    cuisine->setPicture("Chinese.jpg");
    int anhuiCuisineId = addCuisine(cuisine);

    cuisine->setName("法国菜");
    cuisine->setParentId(-1);
    cuisine->setDescription("法国烹饪是在西方世界最具影响和最具特色的烹饪系统，"
                            "法国君主具有较强的王权，在路易十四时达到顶峰，"
                            "宫廷奢华风气在饮食上十分讲究，各种烹饪方法通过效仿的贵族流入民间。"
                            "法国烹饪重视烹饪方法和就餐礼仪，法国盛产葡萄酒（法语：vin）"
                            "和奶酪（fromage），成为法国烹饪必不可少的调料");
    cuisine->setRegionId(franceRegionId);
    cuisine->setPicture("French.jpg");
    int franceCuisineId = addCuisine(cuisine);

    cuisine->setName("意大利菜");
    cuisine->setParentId(-1);
    cuisine->setDescription("義大利飲食文化最早可追溯至公元前四世紀，不斷經歷社會和政治變革至今，"
                            "其中以伊特拉斯坎、古希臘、古羅馬、拜占庭、猶太、阿拉伯等文化影響最為深遠。"
                            "新大陸的發現，帶來了馬鈴薯、番茄、菜椒和玉米等作物引進，直到十八世紀時開始"
                            "大量栽種，成為義大利飲食文化的主要食材。義大利飲食文化以豐富而多元的味覺饗"
                            "宴著稱，各地區亦具不同特色；它是世界上最知名的飲食文化地區之一，"
                            "影響力亦達海外。");
    cuisine->setRegionId(italyRegionId);
    cuisine->setPicture("Italian.jpg");
    int italyCuisineId = addCuisine(cuisine);

    cuisine->setName("日本菜");
    cuisine->setParentId(-1);
    cuisine->setDescription("传统的日本料理主食是米饭，然后再配上其他菜肴——鱼，肉，蔬菜，酱菜，"
                            "以及汤。料理的名称则是用这些菜肴的数目来命名。举例来说，最简单的日本"
                            "餐是“单菜餐”（ichijū-issai，一汁一菜），内容是一碟酱菜（通常是醃黄"
                            "萝卜），一碗饭，以及一碗汤；例如传统的日本早餐，通常是味噌汤，米饭，"
                            "和一碟酱菜。而最常见的料理叫做“三菜餐”（ichijū-sansai，一汁三菜）"
                            "——汤，米饭，和三碟用不同煮法煮出来的菜。这三碟菜通常是一碟生鱼片，"
                            "一碟烤菜，和一碟水煮菜，有的则是蒸菜，炸菜，醋菜，或是淋上酱料的菜。"
                            "“三菜餐”往往会另外附上酱菜以及绿茶。一种很受欢迎的酱菜是梅乾。");
    cuisine->setRegionId(japanRegionId);
    cuisine->setPicture("Japanese.jpg");
    int japanCuisineId = addCuisine(cuisine);

    Q_UNUSED(shandongCuisineId)
    Q_UNUSED(guangdongCuisineId)
    Q_UNUSED(anhuiCuisineId)
    Q_UNUSED(franceCuisineId)
    Q_UNUSED(italyCuisineId)
    Q_UNUSED(japanCuisineId)

    CFlavour* flavour = new CFlavour();
    flavour->setName("酸甜味");
    flavour->setDescription("又酸又甜真好吃");
    flavour->setPicture("");
    int acidSweetFlavourId = addFlavour(flavour);

    flavour->setName("香辣味");
    flavour->setDescription("又香又辣，安逸的坂");
    flavour->setPicture("");
    int smellSpiceFlavourId = addFlavour(flavour);

    CTechnique* technique = new CTechnique();
    technique->setParentId(-1);
    technique->setName("爆");
    technique->setDescription("大火大油，吃得满嘴油");
    int baoTechId = addTechnique(technique);

    technique->setParentId(-1);
    technique->setName("炒");
    technique->setDescription("好吃不上火，是人都喜欢");
    int chaoTechId = addTechnique(technique);

    CDishType* dishType = new CDishType();
    dishType->setParentId(-1);
    dishType->setName("油炸类");
    dishType->setDescription("用油炸。。。");
    dishType->setPicture("");
    int fryDishTypeId = addDishType(dishType);

    CFoodType* foodType = new CFoodType();
    foodType->setParentId(-1);
    foodType->setName("肉类");
    foodType->setDescription("我爱吃肉，你哪？");
    foodType->setPicture("");
    int meatFoodTypeId = addFoodType(foodType);

    CFoodType* foodType2 = new CFoodType();
    foodType2->setParentId(-1);
    foodType2->setName("豆类");
    foodType2->setDescription("黑豆白豆胡豆各种豆");
    foodType2->setPicture("");
    addFoodType(foodType2);

    CRecipe *recipe = new CRecipe();
    //    recipe->setCuisineId(sichuanCuisineId);
    recipe->setName("宫爆鸡丁");
    recipe->setRepresentative(true);
    recipe->setDescription("好吃好吃好吃的板");
    recipe->setFlavourId(acidSweetFlavourId);
    recipe->setTechId(baoTechId);
    recipe->setPrepareTime(30);
    recipe->setCookingTime(10);
    recipe->setDifficulty(2);
    recipe->setDishTypeId(fryDishTypeId);
    recipe->setFoodTypeId(meatFoodTypeId);
    recipe->setServe(2);
    recipe->setPicture("KungPaoChicken.jpg");
    int kongpaoRecipeId = addRecipe(recipe);

    //    recipe->setCuisineId(sichuanCuisineId);
    recipe->setName("回锅肉");
    recipe->setRepresentative(true);
    recipe->setDescription("好吃好吃好吃的板");
    recipe->setFlavourId(smellSpiceFlavourId);
    recipe->setTechId(chaoTechId);
    recipe->setPrepareTime(30);
    recipe->setCookingTime(10);
    recipe->setDifficulty(2);
    recipe->setDishTypeId(fryDishTypeId);
    recipe->setFoodTypeId(meatFoodTypeId);
    recipe->setServe(2);
    recipe->setPicture("Hoikoro.jpg");
    int huiguoRecipeId = addRecipe(recipe);

    CCuisineRecipe* cuisineRecipe = new CCuisineRecipe();
    cuisineRecipe->setCuisineId(sichuanCuisineId);
    cuisineRecipe->setRecipeId(kongpaoRecipeId);
    addCuisineRecipe(cuisineRecipe);

    cuisineRecipe->setCuisineId(sichuanCuisineId);
    cuisineRecipe->setRecipeId(huiguoRecipeId);
    addCuisineRecipe(cuisineRecipe);


    CMethod* method = new CMethod();
    method->setRecipeId(kongpaoRecipeId);
    method->setStep(1);
    method->setDescription("准备调料，1勺醋，1勺酱油，1勺糖，1勺料酒、1勺高汤"
                           "放小碗中调好，姜切片，葱切段，1勺花椒、3个辣椒（辣椒"
                           "可随喜好增加）");
    method->setCostTime(10);
    method->setPicture("1.jpg");
    addMethod(method);

    method->setStep(2);
    method->setDescription("鸡胸肉切1.5CM小丁，用腌料（盐1/2茶勺，料酒1勺，淀粉1茶勺，蛋清1个）腌30分钟");
    method->setCostTime(30);
    method->setPicture("2.jpg");
    addMethod(method);

    method->setStep(3);
    method->setDescription("锅中放少许油，把鸡丁放入滑熟，捞出备用");
    method->setCostTime(2);
    method->setPicture("3.jpg");
    addMethod(method);

    method->setStep(4);
    method->setDescription("再起锅，把花生米小火炸熟，捞出备用");
    method->setCostTime(2);
    method->setPicture("4.jpg");
    addMethod(method);

    method->setStep(5);
    method->setDescription("留少许油，葱、姜、辣椒、花椒倒入锅中以小火爆香");
    method->setCostTime(1);
    method->setPicture("5.jpg");
    addMethod(method);

    method->setStep(6);
    method->setDescription("加入鸡丁和花生米，快速爆炒几下");
    method->setCostTime(1);
    method->setPicture("6.jpg");
    addMethod(method);

    method->setStep(7);
    method->setDescription("加入调料和水淀粉，迅速翻炒，出锅");
    method->setCostTime(1);
    method->setPicture("7.jpg");
    addMethod(method);

    method->setRecipeId(huiguoRecipeId);
    method->setStep(1);
    method->setDescription("锅中倒入清水煮沸，然后投入拍散的生姜和蒜、葱段、"
                           "花椒熬出味道。放入猪肉，肉滚至六成熟即可捞出，"
                           "宁不及而勿过，不要彻底放凉后再切，容易导致使肥瘦分离");
    method->setCostTime(10);
    method->setPicture("1.jpg");
    addMethod(method);

    method->setStep(2);
    method->setDescription("肉汤捞出葱姜蒜和花椒后加热，放入切好的冬瓜片或萝卜片煮熟，"
                           "放少许盐和鸡精就是美味的“连锅汤”喽");
    method->setCostTime(5);
    method->setPicture("2.jpg");
    addMethod(method);

    method->setStep(3);
    method->setDescription("用浸冷水的办法使肉表面不至于烫手时再切成片，"
                           "蒜苗洗净斜切成菱形备用，青红椒洗净切成三角形备用，"
                           "豆腐干切成三角形备用，准备好郫县豆瓣酱和甜面酱（或豆豉）");
    method->setCostTime(5);
    method->setPicture("");
    addMethod(method);

    method->setStep(4);
    method->setDescription("炒锅中倒入少许油，油热后用锅铲使油遍布锅壁。然后弃之不用，"
                           "重新加入凉油。这样的作用是给锅身布上一层油膜，肉片下锅的时候不至于沾锅");
    method->setCostTime(1);
    method->setPicture("");
    addMethod(method);

    method->setStep(5);
    method->setDescription("待油温四成热时放入肉片爆炒，炒至肉片打卷（俗称：灯盏窝）"
                           "后，倒入郫县豆瓣酱和甜面酱（或豆豉），然后将酱和肉片混合翻"
                           "炒几下，调少许酱油上色，再调入少许白糖增味");
    method->setCostTime(2);
    method->setPicture("5.jpg");
    addMethod(method);

    method->setStep(6);
    method->setDescription("最后放入豆腐干、青红椒和蒜苗炒至断生，调入少许盐和鸡精，翻炒几下即可");
    method->setCostTime(1);
    method->setPicture("6.jpg");
    addMethod(method);

    CIngredientCategory *cat = new CIngredientCategory();
    cat->setName("肉");
    cat->setDescription("我爱吃肉心情好好，5 wohoo 5");
    cat->setPicture("");
    int meatCat = addIngredientCategory(cat);

    cat->setName("蔬菜");
    cat->setDescription("低碳环保，少吃一点肉，少排一点碳");
    cat->setPicture("");
    int vegCat = addIngredientCategory(cat);

    cat->setName("调料");
    cat->setDescription("少吃盐，当心你的血管");
    cat->setPicture("");
    int seasoningCat = addIngredientCategory(cat);

    cat->setName("豆类");
    cat->setDescription("豆子吃了很好哦");
    cat->setPicture("");
    int beanCat = addIngredientCategory(cat);

    cat->setName("坚果类");
    cat->setDescription("坚果很有营养");
    cat->setPicture("");
    int nutCat = addIngredientCategory(cat);

    cat->setName("蛋类");
    cat->setDescription("煎鸡蛋？");
    cat->setPicture("");
    int eggCat = addIngredientCategory(cat);

    Q_UNUSED(nutCat)
    Q_UNUSED(eggCat)

    CIngredient * ingredient = new CIngredient();
    ingredient->setName("猪肉");
    ingredient->setDescription("猪肉含蛋白质、脂肪、碳水化合物、"
                               "磷、钙、铁、维生素B卜维生素B2、烟酸等成分"
                               "，是肉类中含B族维生素最多的，相当于牛羊肉的7倍。");
    ingredient->setPicture("Pork.jpg");
    ingredient->setCategoryId(meatCat);
    int porkIngr = addIngredient(ingredient);

    ingredient->setName("豆腐干");
    ingredient->setDescription("1. 豆腐干中含有丰富蛋白质，而且豆腐蛋白属完全蛋白，"
                               "不仅含有人体必需的8种氨基酸，而且其比例也接近人体需要，"
                               "营养价值较高\n"
                               "2. 豆腐干含有的卵磷脂可除掉附在血管壁上的胆固醇，防"
                               "止血管硬化，预防心血管疾病，保护心脏\n"
                               "3. 含有多种矿物质，补充钙质，防止因缺钙引起的骨质疏松，"
                               "促进骨骼发育，对小儿、老人的骨骼生长极为有利。");
    ingredient->setPicture("Doufu.jpg");
    ingredient->setCategoryId(beanCat);
    int doufuIngr = addIngredient(ingredient);

    ingredient->setName("红椒");
    ingredient->setDescription("一年生或多年生草本。茎直立，多分枝。单叶互生，叶片广卵形"
                               "，先端渐尖，叶柄较长。花单生于叶腋内，花冠黄色或绿色。果实球形，"
                               "外具瓣状突起，有红色、绿色和黄色三种。种子扁圆形，淡黄色。花期夏季。");
    ingredient->setPicture("RedChili.jpg");
    ingredient->setCategoryId(vegCat);
    int redChiliIngr = addIngredient(ingredient);

    ingredient->setName("青椒");
    ingredient->setDescription("青椒是一年生或多年生草本植物，"
                               "由原产中南美洲热带地区的辣椒演化而来，"
                               "品种有绿、红、黄等颜色。");
    ingredient->setPicture("GreenChili.jpg");
    ingredient->setCategoryId(vegCat);
    int greenChiliIngr = addIngredient(ingredient);

    ingredient->setName("食盐");
    ingredient->setDescription("食盐是一种调料，是海水或盐井、盐池、盐泉中的盐水经煎晒而成的结晶，无色或白色。它的香味有很强的渗透力，能提出各种原料中的鲜味，调制出许多类味型的香味，有“百味之王”的美称。");
    ingredient->setPicture("Salt.jpg");
    ingredient->setCategoryId(seasoningCat);
    int saltIngr = addIngredient(ingredient);

    ingredient->setName("酱油");
    ingredient->setDescription("酱油俗称豉油，主要由大豆，淀粉、小麦、食盐经过制油、发酵等程序酿制而成的。酱油的成分比较复杂，除食盐的成分外，还有多种氨基酸、糖类、有机酸、色素及香料民分。以咸味为主，亦有鲜味、香味等。它能增加和改善菜肴的口味，还能增添或改变菜肴的色泽。我国人民在数千年前就已经掌握酿制工艺了。酱油一般有老抽和生抽两种：老抽较咸，用于提色；生抽用于提鲜。");
    ingredient->setPicture("SoySauce.jpg");
    ingredient->setCategoryId(seasoningCat);
    int soySauceIngr = addIngredient(ingredient);

    ingredient->setName("鸡精");
    ingredient->setDescription("鸡精是以新鲜鸡肉、鸡骨、鸡蛋为原料制成的复合增鲜、增香的调味料。可以用于使用味精的所有场合，适量加入菜肴、汤羹、面食中均能达到效果。鸡精中除含有谷氨酸钠外，更含有多种氨基酸。它是既能增加人们的食欲，又能提供一定营养的家常调味品。 ");
    ingredient->setPicture("ChickenEssence.jpg");
    ingredient->setCategoryId(seasoningCat);
    int chickenEssenceIngr = addIngredient(ingredient);

    ingredient->setName("葱");
    ingredient->setDescription("葱原产于西伯利亚，是百合科草本植物葱的茎与叶。中国栽培大葱的历史十分悠久，主要产地分布于山东、河北、河南等省，北方人以大葱为主，南方人多食小葱。葱不仅是家庭必备调味佐餐佳品，而且有着很好的药用功效。");
    ingredient->setPicture("Scallion.jpg");
    ingredient->setCategoryId(seasoningCat);
    int scallionIngr = addIngredient(ingredient);

    ingredient->setName("姜");
    ingredient->setDescription("姜属姜科，为植物姜的干燥根茎或鲜根茎，多年生草本植物。原产印度、马来西亚，我国自古栽培，周年食用。姜供食用的部位为不规则的块茎，呈灰白或黄色，具有辛辣味。姜按用途和收获季节不同而有嫩姜和老姜之分。嫩姜多在八月份挖掘，一般含水多，纤维少，辛辣味淡薄，除做调味品外，尚可炒食，做姜糖等；老姜多在十一月份挖掘，水分少，辛辣味浓，主要用做调味。姜是一种极为重要的调味品，同时也可作为蔬菜单独食用，而且还是一味重要的中药材。它可将自身的辛辣味和特殊芳香渗入到菜肴中，使之鲜美可口，味道清香。");
    ingredient->setPicture("Ginger.jpg");
    ingredient->setCategoryId(seasoningCat);
    int gingerIngr = addIngredient(ingredient);

    ingredient->setName("蒜");
    ingredient->setDescription("蒜原产于中亚，相传是汉代张骞出使西域时带回中国的。因其出于胡人居住地，故有“胡蒜”之称。大蒜属于百合科植物，也是日常的菜类和调料，被誉为“天然抗生素”。");
    ingredient->setPicture("Garlic.jpg");
    ingredient->setCategoryId(seasoningCat);
    int garlicIngr = addIngredient(ingredient);

    ingredient->setName("青蒜");
    ingredient->setDescription("青蒜是大蒜青绿色的幼苗，以其柔嫩的蒜叶和叶鞘供食用。品质好的青蒜应该鲜嫩，株高在35厘米以上，叶色鲜绿，不黄不烂，毛根白色不枯萎，而且辣味较浓。");
    ingredient->setPicture("Leek.jpg");
    ingredient->setCategoryId(seasoningCat);
    int leekIngr = addIngredient(ingredient);

    ingredient->setName("花椒");
    ingredient->setDescription("花椒为芸香科灌木或小乔木植物青椒的干燥成熟果皮，一般在立秋前后成熟。产于四川、陕西、河南、河北、山西、云南等省，以四川产的质量好，以河北、山西产量为高。花椒是中国特有的香料，位列调料“十三香”之首。无论红烧、卤味、小菜、四川泡菜、鸡鸭鱼羊牛等菜肴均可用到它，也可粗磨成粉和盐拌匀为椒盐，供蘸食用。分为大椒和步椒两种，为良好的调味佐料，也可榨油，出油率在25%以上。花椒油有浓厚的香味，是一种很好的食用油。生产花椒味麻且辣，炒熟后香味才溢出。在烹调上既能单独使用，如花椒面；也能与其他原料配制成调味品，用途极广，效果甚好，如五香面、花椒盐、葱椒盐等。 ");
    ingredient->setPicture("Pepper.jpg");
    ingredient->setCategoryId(seasoningCat);
    int pepperIngr = addIngredient(ingredient);

    ingredient->setName("豆瓣辣酱");
    ingredient->setDescription("豆瓣辣酱是用蚕豆，辣椒，香料，精盐等酿制而成。根据用途可分为助餐型和调味型两大类。助餐型如资阳，成都，重庆，等地所产的香油，金钩，火腿等豆瓣，具有香鲜醇厚，微带辣味，豆瓣酥软的特点；调味型如郫县，成都，重庆等地所的郫县豆瓣，细红豆瓣，戏豆瓣酱等。 ");
    ingredient->setPicture("BeenChiliSauce.jpg");
    ingredient->setCategoryId(seasoningCat);
    int beenChiliSauceIngr = addIngredient(ingredient);

    ingredient->setName("甜面酱");
    ingredient->setDescription("甜面酱是以面粉为主要原料，经制曲和保温发酵制成的一种酱状调味品。其味甜中带咸，同时有酱香和酯香，适用于烹饪酱爆和酱烧菜，如“酱爆肉丁”等，还可蘸食大葱、黄瓜、烤鸭等菜品。");
    ingredient->setPicture("SweetSauce.jpg");
    ingredient->setCategoryId(seasoningCat);
    int sweetSauceIngr = addIngredient(ingredient);

    ingredient->setName("鸡胸脯肉");
    ingredient->setDescription("鸡胸肉是在胸部里侧的肉，形状像斗笠。肉质细嫩，滋味鲜美，营养丰富，能滋补养身。 却只含有与虾、螃蟹等相当的脂肪。是不必担心因动物性脂肪而使人体受到伤害的唯一的肉类。鸡胸肉是鸡肉中属于蛋白质含量较多的部位。 ");
    ingredient->setPicture("ChickenBreastMeat.jpg");
    ingredient->setCategoryId(meatCat);
    int chickenBreastMeatIngr = addIngredient(ingredient);

    ingredient->setName("花生");
    ingredient->setDescription("花生是豆科植物落花生的种子，因为是在花落以后，花茎钻入泥土而结果，所以又称“落花生”，又由于营养价值高，吃了可延年益寿，故又称为“长寿果”。");
    ingredient->setPicture("Peanut.jpg");
    ingredient->setCategoryId(seasoningCat);
    int peanutIngr = addIngredient(ingredient);

    ingredient->setName("鸡蛋清");
    ingredient->setDescription("鸡蛋的蛋白可用来制作蛋泡糊或上浆；鸡蛋清富含蛋白质和人体必需的8种氨基酸和少量醋酸。 ");
    ingredient->setPicture("EggWhite.jpg");
    ingredient->setCategoryId(seasoningCat);
    int eggWhiteIngr = addIngredient(ingredient);

    ingredient->setName("朝天椒");
    ingredient->setDescription("辣椒原产于中南美洲的热带地区，以墨西哥最为盛产。既可以用来制作各种形式的调味料，又能烹制各种美味佳肴，让人胃口大开，特别是红辣椒，印度人称它为“红色牛排”。在中国，辣椒在湖南、四川等地都是非常重要的调味品。");
    ingredient->setPicture("Chilli.jpg");
    ingredient->setCategoryId(seasoningCat);
    int chilliIngr = addIngredient(ingredient);

    ingredient->setName("醋");
    ingredient->setDescription("醋是一种发酵的酸味液态调味品，以含淀粉类的粮食(高粱、黄米、糯米、籼米等)为主料，谷糠、稻皮等为辅料，经过发酵酿造而成。醋在烹调中为主要的调味品之一,以酸味为主,且有芳香味,用途较广，是糖醋味的主要原料。");
    ingredient->setPicture("Vinegar.jpg");
    ingredient->setCategoryId(seasoningCat);
    int vinegarIngr = addIngredient(ingredient);

    ingredient->setName("料酒");
    ingredient->setDescription("料酒就是专门用于烹饪调味的酒。在我国的应用已有上千年的历史，日本、美国、欧洲的某些国家也有使用料酒的习惯。");
    ingredient->setPicture("CookingWine.jpg");
    ingredient->setCategoryId(seasoningCat);
    int cookingWineIngr = addIngredient(ingredient);


    ingredient->setName("淀粉");
    ingredient->setDescription("勾芡用的淀粉，又叫做团粉，是由多个葡萄糖分子缩合而成的多糖聚合物。烹调用的淀粉，主要有绿豆淀粉、马铃薯淀粉、麦类淀粉、菱角淀粉、藕淀粉、玉米淀粉等。");
    ingredient->setPicture("Starch.jpg");
    ingredient->setCategoryId(seasoningCat);
    int starchIngr = addIngredient(ingredient);


    CUnitType* unitType = new CUnitType();
    unitType->setName("g");
    int gramUnitType = addUnitType(unitType);

    unitType->setName("mg");
    int mgUnitType = addUnitType(unitType);

    unitType->setName("kJ");
    int kjUnitType = addUnitType(unitType);

    unitType->setName("mgRE");
    int mgReUnitType = addUnitType(unitType);

    unitType->setName("mg a-TE");
    int mgATeUnitType = addUnitType(unitType);

    unitType->setName("mgDFE");
    int mgDfeUnitType = addUnitType(unitType);

    unitType->setName("瓣");
    int banUnitType = addUnitType(unitType);

    unitType->setName("个");
    int geUnitType = addUnitType(unitType);

    unitType->setName("根");
    int genUnitType = addUnitType(unitType);

    unitType->setName("段");
    int duanUnitType = addUnitType(unitType);

    unitType->setName("小块");
    int xiaokuaiUnitType = addUnitType(unitType);

    unitType->setName("汤匙");
    int tangchiUnitType = addUnitType(unitType);

    unitType->setName("粒");
    int liUnitType = addUnitType(unitType);

    unitType->setName("茶匙");
    int chachiUnitType = addUnitType(unitType);

    unitType->setName("少许");
    int shaoxuUnitType = addUnitType(unitType);

    unitType->setName("条");
    int tiaoUnitType = addUnitType(unitType);

    CRecipeIngredient* recipeIngredient = new CRecipeIngredient();
    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(porkIngr);
    recipeIngredient->setUnitTypeId(gramUnitType);
    recipeIngredient->setQuantity(500);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(doufuIngr);
    recipeIngredient->setUnitTypeId(gramUnitType);
    recipeIngredient->setQuantity(200);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(redChiliIngr);
    recipeIngredient->setUnitTypeId(geUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(greenChiliIngr);
    recipeIngredient->setUnitTypeId(geUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(leekIngr);
    recipeIngredient->setUnitTypeId(genUnitType);
    recipeIngredient->setQuantity(4);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(saltIngr);
    recipeIngredient->setUnitTypeId(shaoxuUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(scallionIngr);
    recipeIngredient->setUnitTypeId(duanUnitType);
    recipeIngredient->setQuantity(3);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(soySauceIngr);
    recipeIngredient->setUnitTypeId(chachiUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(chickenEssenceIngr);
    recipeIngredient->setUnitTypeId(shaoxuUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(gingerIngr);
    recipeIngredient->setUnitTypeId(xiaokuaiUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(garlicIngr);
    recipeIngredient->setUnitTypeId(banUnitType);
    recipeIngredient->setQuantity(3);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(pepperIngr);
    recipeIngredient->setUnitTypeId(liUnitType);
    recipeIngredient->setQuantity(15);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(sweetSauceIngr);
    recipeIngredient->setUnitTypeId(tangchiUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(huiguoRecipeId);
    recipeIngredient->setIngredientId(beenChiliSauceIngr);
    recipeIngredient->setUnitTypeId(tangchiUnitType);
    recipeIngredient->setQuantity(2);
    addRecipeIngredient(recipeIngredient);

    //宫保鸡丁原料
    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(chickenBreastMeatIngr);
    recipeIngredient->setUnitTypeId(tiaoUnitType);
    recipeIngredient->setQuantity(2);
    addRecipeIngredient(recipeIngredient);


    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(peanutIngr);
    recipeIngredient->setUnitTypeId(gramUnitType);
    recipeIngredient->setQuantity(20);
    addRecipeIngredient(recipeIngredient);


    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(eggWhiteIngr);
    recipeIngredient->setUnitTypeId(geUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(chilliIngr);
    recipeIngredient->setUnitTypeId(gramUnitType);
    recipeIngredient->setQuantity(20);
    addRecipeIngredient(recipeIngredient);

    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(saltIngr);
    recipeIngredient->setUnitTypeId(chachiUnitType);
    recipeIngredient->setQuantity(0.5);
    addRecipeIngredient(recipeIngredient);


    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(soySauceIngr);
    recipeIngredient->setUnitTypeId(chachiUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);


    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(vinegarIngr);
    recipeIngredient->setUnitTypeId(chachiUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);


    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(garlicIngr);
    recipeIngredient->setUnitTypeId(genUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);


    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(gingerIngr);
    recipeIngredient->setUnitTypeId(xiaokuaiUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);


    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(pepperIngr);
    recipeIngredient->setUnitTypeId(chachiUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);


    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(cookingWineIngr);
    recipeIngredient->setUnitTypeId(chachiUnitType);
    recipeIngredient->setQuantity(2);
    addRecipeIngredient(recipeIngredient);


    recipeIngredient->setRecipeId(kongpaoRecipeId);
    recipeIngredient->setIngredientId(starchIngr);
    recipeIngredient->setUnitTypeId(chachiUnitType);
    recipeIngredient->setQuantity(1);
    addRecipeIngredient(recipeIngredient);

    CNutritionConsume* consume = new CNutritionConsume();
    consume->setName("极轻");
    consume->setDescription("以坐着为主的工作，如办公室工作，组装或修理收音机、钟表等");
    consume->setPicture("VeryLow.png");
    int veryLowConsume = addNutritionConsume(consume);

    consume->setName("轻");
    consume->setDescription("以站着或少量走动为主的工作，如店员售货，化学实验操作，教员讲课等");
    consume->setPicture("Low.jpg");
    int lowConsume = addNutritionConsume(consume);


    consume->setName("中");
    consume->setDescription("以轻度活动为主的工作，如学生的日常活动，机动车驾驶、电工安装、金工切削等");
    consume->setPicture("Medium.png");
    int mediumConsume = addNutritionConsume(consume);

    consume->setName("重");
    consume->setDescription("以较重的活动为主的工作，如非机械化的农业劳动、炼钢、舞蹈、体育运动等");
    consume->setPicture("Heavy.png");
    int heavyConsume = addNutritionConsume(consume);

    consume->setName("极重");
    consume->setDescription("以极重的活动为主的工作，如非机械化的装卸、伐木、采矿、砸石等");
    consume->setPicture("VeryHeavy.png");
    int veryHeavyConsume = addNutritionConsume(consume);

    //
    Q_UNUSED(veryLowConsume)
    Q_UNUSED(mediumConsume)
    Q_UNUSED(heavyConsume)
    Q_UNUSED(veryHeavyConsume)
    //

    consume->setName("中国食品标签营养素参考值(NRV)");
    consume->setDescription("中国食品标签营养素参考值（Nutrient Reference Values，NRV，简称“营养素参考值”）是食品营养标签上比较食品营养素含量多少的参考标准，是消费者选择食品时的一种营养参照尺度。营养素参考值依据我国居民膳食营养素推荐摄入量（RNI）和适宜摄入量（AI）而制定。");
    consume->setPicture("NRV.jpg");
    int nrvConsume = addNutritionConsume(consume);

    CNutrition * nutrition = new CNutrition();
    nutrition->setName("Energy");
    nutrition->setDescription("");
    int energyNutr = addNutrition(nutrition);

    nutrition->setName("Protein");
    nutrition->setDescription("");
    int proteinNutr = addNutrition(nutrition);

    nutrition->setName("Fat");
    nutrition->setDescription("");
    int fatNutr = addNutrition(nutrition);

    nutrition->setName("Saturated Fatty Acid");
    nutrition->setDescription("");
    int saturatedFatNutr = addNutrition(nutrition);

    nutrition->setName("Cholesterol");
    nutrition->setDescription("");
    int cholesterolNutr = addNutrition(nutrition);

    nutrition->setName("Carbohydrate");
    nutrition->setDescription("");
    int carbohydrateNutr = addNutrition(nutrition);

    nutrition->setName("Dietary Fiber");
    nutrition->setDescription("");
    int dietaryFiberNutr = addNutrition(nutrition);

    nutrition->setName("Vitamin A");
    nutrition->setDescription("");
    int vANutr = addNutrition(nutrition);

    nutrition->setName("Vitamin D");
    nutrition->setDescription("");
    int vDNutr = addNutrition(nutrition);

    nutrition->setName("Vitamin E");
    nutrition->setDescription("");
    int vENutr = addNutrition(nutrition);

    nutrition->setName("Vitamin K");
    nutrition->setDescription("");
    int vKNutr = addNutrition(nutrition);

    nutrition->setName("Vitamin B1");
    nutrition->setDescription("");
    int vB1Nutr = addNutrition(nutrition);

    nutrition->setName("Vitamin B2");
    nutrition->setDescription("");
    int vB2Nutr = addNutrition(nutrition);

    nutrition->setName("Vitamin B6");
    nutrition->setDescription("");
    int vB6Nutr = addNutrition(nutrition);

    nutrition->setName("Vitamin B12");
    nutrition->setDescription("");
    int vB12Nutr = addNutrition(nutrition);

    nutrition->setName("Vitamin C");
    nutrition->setDescription("");
    int vCNutr = addNutrition(nutrition);

    nutrition->setName("Nicotinic Acid");
    nutrition->setDescription("");
    int nicotinicAcidNutr = addNutrition(nutrition);

    nutrition->setName("Folic Acid");
    nutrition->setDescription("");
    int folicAcidNutr = addNutrition(nutrition);

    nutrition->setName("Pantothenic Acid");
    nutrition->setDescription("");
    int pantothenicAcidNutr = addNutrition(nutrition);

    nutrition->setName("Biotin");
    nutrition->setDescription("");
    int biotinNutr = addNutrition(nutrition);

    nutrition->setName("Sinkaline");
    nutrition->setDescription("");
    int sinkalineNutr = addNutrition(nutrition);

    nutrition->setName("Calcium");
    nutrition->setDescription("");
    int calciumNutr = addNutrition(nutrition);

    nutrition->setName("Phosphorus");
    nutrition->setDescription("");
    int phosphorusNutr = addNutrition(nutrition);

    nutrition->setName("Potassium");
    nutrition->setDescription("");
    int potassiumNutr = addNutrition(nutrition);

    nutrition->setName("Sodium");
    nutrition->setDescription("");
    int sodiumNutr = addNutrition(nutrition);

    nutrition->setName("Magnesium");
    nutrition->setDescription("");
    int magnesiumNutr = addNutrition(nutrition);

    nutrition->setName("Iron");
    nutrition->setDescription("");
    int ironNutr = addNutrition(nutrition);

    nutrition->setName("Zinc");
    nutrition->setDescription("");
    int zincNutr = addNutrition(nutrition);

    nutrition->setName("iodine");
    nutrition->setDescription("");
    int iodineNutr = addNutrition(nutrition);

    nutrition->setName("Selenium");
    nutrition->setDescription("");
    int seleniumNutr = addNutrition(nutrition);

    nutrition->setName("Copper");
    nutrition->setDescription("");
    int copperNutr = addNutrition(nutrition);

    nutrition->setName("Fluorine");
    nutrition->setDescription("");
    int fluorineNutr = addNutrition(nutrition);

    nutrition->setName("Chromium");
    nutrition->setDescription("");
    int chromiumNutr = addNutrition(nutrition);

    nutrition->setName("Manganese");
    nutrition->setDescription("");
    int manganeseNutr = addNutrition(nutrition);

    nutrition->setName("Molybdenum");
    nutrition->setDescription("");
    int molybdenumNutr = addNutrition(nutrition);

    CConsumeNutrition* conNu = new CConsumeNutrition();
    conNu->setConsumeId(lowConsume);
    conNu->setNutritionId(energyNutr);
    conNu->setUnitTypeId(kjUnitType);
    conNu->setQuantity(8400);
    addConsumeNutrition(conNu);

    conNu->setConsumeId(nrvConsume);
    conNu->setNutritionId(energyNutr);
    conNu->setUnitTypeId(kjUnitType);
    conNu->setQuantity(8400);
    addConsumeNutrition(conNu);

    conNu->setConsumeId(nrvConsume);
    conNu->setNutritionId(energyNutr);
    conNu->setUnitTypeId(kjUnitType);
    conNu->setQuantity(8400);
    addConsumeNutrition(conNu);

    conNu->setConsumeId(nrvConsume);
    conNu->setNutritionId(energyNutr);
    conNu->setUnitTypeId(kjUnitType);
    conNu->setQuantity(8400);
    addConsumeNutrition(conNu);

    conNu->setConsumeId(nrvConsume);
    conNu->setNutritionId(energyNutr);
    conNu->setUnitTypeId(kjUnitType);
    conNu->setQuantity(8400);
    addConsumeNutrition(conNu);

    conNu->setConsumeId(nrvConsume);
    conNu->setNutritionId(energyNutr);
    conNu->setUnitTypeId(kjUnitType);
    conNu->setQuantity(8400);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(proteinNutr);
    conNu->setUnitTypeId(gramUnitType);
    conNu->setQuantity(60);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(fatNutr);
    conNu->setUnitTypeId(gramUnitType);
    conNu->setQuantity(60);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(saturatedFatNutr);
    conNu->setUnitTypeId(gramUnitType);
    conNu->setQuantity(20);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(cholesterolNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(30);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(carbohydrateNutr);
    conNu->setUnitTypeId(gramUnitType);
    conNu->setQuantity(300);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(dietaryFiberNutr);
    conNu->setUnitTypeId(gramUnitType);
    conNu->setQuantity(25);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(vANutr);
    conNu->setUnitTypeId(mgReUnitType);
    conNu->setQuantity(800);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(vDNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(5);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(vENutr);
    conNu->setUnitTypeId(mgATeUnitType);
    conNu->setQuantity(14);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(vKNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(80);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(vB1Nutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(1.4);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(vB2Nutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(1.4);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(vB6Nutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(1.4);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(vB12Nutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(2.4);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(vCNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(100);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(nicotinicAcidNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(14);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(folicAcidNutr);
    conNu->setUnitTypeId(mgDfeUnitType);
    conNu->setQuantity(400);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(pantothenicAcidNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(5);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(biotinNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(30);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(sinkalineNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(450);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(calciumNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(800);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(phosphorusNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(700);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(potassiumNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(2000);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(sodiumNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(2000);
    addConsumeNutrition(conNu);


    conNu->setNutritionId(magnesiumNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(300);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(ironNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(15);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(zincNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(15);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(iodineNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(150);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(seleniumNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(50);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(copperNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(1.5);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(fluorineNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(1);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(chromiumNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(50);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(manganeseNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(3);
    addConsumeNutrition(conNu);

    conNu->setNutritionId(molybdenumNutr);
    conNu->setUnitTypeId(mgUnitType);
    conNu->setQuantity(40);
    addConsumeNutrition(conNu);
}

QSqlQuery *CEngine::query(QString &sqlStr, bool nonSelect) {
    QSqlQuery *query = new QSqlQuery();

    if (query->exec(sqlStr)) {
        return query;
    }
    else {
        qDebug()<<"sql/query:"<<sqlStr<<"execute failed"<<query->lastError();
        delete query;
        return NULL;
    }
}

QObject *CEngine::cuisineModel(int parentId) {
    return new CCuisineModel(parentId);
}

QObject *CEngine::recipeModel(int cuisineId) {
    return new CRecipeModel(cuisineId);
}

QObject* CEngine::cuisine(int cuisineId) {
    CCuisine *cuisine = new CCuisine();

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableCuisine + KWhere
                   + KCuisineId + KEqual + QString::number(cuisineId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        cuisine->setValid(true);
        cuisine->setId(sqlQuery->value(sqlQuery->record().indexOf(KCuisineId)).toInt());
        cuisine->setParentId(sqlQuery->value(sqlQuery->record().indexOf(KCuisineParentId)).toInt());
        cuisine->setName(sqlQuery->value(sqlQuery->record().indexOf(KCuisineName)).toString());
        cuisine->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KCuisineDescription)).toString());
        cuisine->setRegionId(sqlQuery->value(sqlQuery->record().indexOf(KCuisineRegionId)).toInt());
        cuisine->setPicture(pictureFolderPath()
                            + KCuisinePicturePrefix
                            + sqlQuery->value(sqlQuery->record().indexOf(KCuisinePicture)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return cuisine;
}

int CEngine::addCuisine(QObject* cuisine) {
    int addedId = KInvalidId;
    CCuisine * obj = static_cast<CCuisine*>(cuisine);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableCuisine);
    //use autoincrement, so set id to NULL
    helper->addNull(KCuisineId);
    helper->addValue(KCuisineParentId, obj->parentId());
    helper->addValue(KCuisineName, obj->name());
    helper->addValue(KCuisineDescription, obj->description());
    helper->addValue(KCuisineRegionId, obj->regionId());
    helper->addValue(KCuisinePicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::cuisineRecipe(int cuisineRecipeId) {
    CCuisineRecipe *cuisineRecipe = new CCuisineRecipe();

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableCuisineRecipe + KWhere
                   + KCuisineRecipeId + KEqual + QString::number(cuisineRecipeId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        cuisineRecipe->setValid(true);
        cuisineRecipe->setId(sqlQuery->value(sqlQuery->record().indexOf(KCuisineRecipeId)).toInt());
        cuisineRecipe->setRecipeId(sqlQuery->value(sqlQuery->record().indexOf(KCuisineRecipeRecipeId)).toInt());
        cuisineRecipe->setCuisineId(sqlQuery->value(sqlQuery->record().indexOf(KCuisineRecipeCuisineId)).toInt());
        delete sqlQuery;
    }

    delete sqlStr;
    return cuisineRecipe;
}

int CEngine::addCuisineRecipe(QObject* cuisineRecipe) {
    int addedId = KInvalidId;
    CCuisineRecipe * obj = static_cast<CCuisineRecipe*>(cuisineRecipe);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableCuisineRecipe);
    //use autoincrement, so set id to NULL
    helper->addNull(KCuisineRecipeId);
    helper->addValue(KCuisineRecipeCuisineId, obj->cuisineId());
    helper->addValue(KCuisineRecipeRecipeId, obj->recipeId());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}


bool CEngine::hasChildCuisine(int cuisineId) {
    return childCuisineCount(cuisineId) > 0;
}

int CEngine::childCuisineCount(int cuisineId) {
    int count(0);

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KCountAll + KFrom + KTableCuisine +
                   KWhere + KCuisineParentId + KEqual + QString::number(cuisineId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        count = sqlQuery->value(0).toInt();
        delete sqlQuery;
    }

    delete sqlStr;
    return count;
}

QObject* CEngine::ingredient(int regredientId) {
    CIngredient *ingredient = new CIngredient();

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableIngredient + KWhere
                   + KIngredientId + KEqual + QString::number(regredientId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        ingredient->setValid(true);
        ingredient->setId(sqlQuery->value(sqlQuery->record().indexOf(KIngredientId)).toInt());
        ingredient->setName(sqlQuery->value(sqlQuery->record().indexOf(KIngredientName)).toString());
        ingredient->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KIngredientDescription)).toString());
        ingredient->setCategoryId(sqlQuery->value(sqlQuery->record().indexOf(KIngredientCategoryIdentify)).toInt());
        ingredient->setPicture(pictureFolderPath()
                               + KIngredientPicturePrefix
                               + sqlQuery->value(sqlQuery->record().indexOf(KIngredientPicture)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return ingredient;
}

QObjectList CEngine::getAllIngredient()
{
    QObjectList list;

    QString *sqlStr = new QString;
    sqlStr->append(KSelect + KAll + KFrom + KTableIngredient);
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        // Maybe have more than one ingredient
        while(sqlQuery->next()) {
            CIngredient *ingredient = new CIngredient();
            ingredient->setValid(true);
            ingredient->setId(sqlQuery->value(sqlQuery->record().indexOf(KIngredientId)).toInt());
            ingredient->setName(sqlQuery->value(sqlQuery->record().indexOf(KIngredientName)).toString());
            ingredient->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KIngredientDescription)).toString());
            ingredient->setCategoryId(sqlQuery->value(sqlQuery->record().indexOf(KIngredientCategoryIdentify)).toInt());
            ingredient->setPicture(pictureFolderPath()
                                   + KIngredientPicturePrefix
                                   + sqlQuery->value(sqlQuery->record().indexOf(KIngredientPicture)).toString());
            list.append(ingredient);
        }
        delete sqlQuery;
    }

    delete sqlStr;
    return list;
}

int CEngine::addIngredient(QObject* ingredient) {
    int addedId = KInvalidId;
    CIngredient * obj = static_cast<CIngredient*>(ingredient);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableIngredient);
    //use autoincrement, so set id to NULL
    helper->addNull(KIngredientId);
    helper->addValue(KIngredientName, obj->name());
    helper->addValue(KIngredientDescription, obj->description());
    helper->addValue(KIngredientCategoryIdentify, obj->categoryId());
    helper->addValue(KIngredientPicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::ingredientCategory(int regredientCatId) {
    CIngredientCategory *ingredientCat = new CIngredientCategory();

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableIngredientCategory + KWhere
                   + KIngredientCategoryId + KEqual + QString::number(regredientCatId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        ingredientCat->setValid(true);
        ingredientCat->setId(sqlQuery->value(sqlQuery->record().indexOf(KIngredientCategoryId)).toInt());
        ingredientCat->setName(sqlQuery->value(sqlQuery->record().indexOf(KIngredientCategoryName)).toString());
        ingredientCat->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KIngredientCategoryDescription)).toString());
        ingredientCat->setPicture(pictureFolderPath()
                                  + KIngredientCategoryPicturePrefix
                                  + sqlQuery->value(sqlQuery->record().indexOf(KIngredientCategoryPicture)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return ingredientCat;
}

int CEngine::addIngredientCategory(QObject* ingredientCat) {
    int addedId = KInvalidId;
    CIngredientCategory * obj = static_cast<CIngredientCategory*>(ingredientCat);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableIngredientCategory);
    //use autoincrement, so set id to NULL
    helper->addNull(KIngredientCategoryId);
    helper->addValue(KIngredientCategoryName, obj->name());
    helper->addValue(KIngredientCategoryDescription, obj->description());
    helper->addValue(KIngredientCategoryPicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObjectList CEngine::recipeIngredients(int recipeId) {
    QObjectList list;

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableRecipeIngredient + KWhere
                   + KRecipeIngredientRecipeId + KEqual + QString::number(recipeId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        //may have multiple ingredients
        while(sqlQuery->next()) {
            CRecipeIngredient *ingredient = new CRecipeIngredient();
            ingredient->setValid(true);
            ingredient->setId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientId)).toInt());
            ingredient->setIngredientId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientIngredientId)).toInt());
            ingredient->setRecipeId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientRecipeId)).toInt());
            ingredient->setQuantity(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientQuantity)).toDouble());
            ingredient->setUnitTypeId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientUnitTypeId)).toInt());
            list.append(ingredient);
        }
        delete sqlQuery;
    }

    delete sqlStr;
    return list;
}

QObject* CEngine::recipeIngredient(int recipeIngredientId) {
    CRecipeIngredient* ingredient = new CRecipeIngredient();
    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableRecipeIngredient + KWhere
                   + KRecipeIngredientId + KEqual + QString::number(recipeIngredientId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        ingredient->setValid(true);
        ingredient->setId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientId)).toInt());
        ingredient->setIngredientId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientIngredientId)).toInt());
        ingredient->setRecipeId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientRecipeId)).toInt());
        ingredient->setQuantity(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientQuantity)).toDouble());
        ingredient->setUnitTypeId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeIngredientUnitTypeId)).toInt());
        delete sqlQuery;
    }

    delete sqlStr;
    return ingredient;
}

int CEngine::addRecipeIngredient(QObject* recipeIngredient) {
    int addedId = KInvalidId;
    CRecipeIngredient * obj = static_cast<CRecipeIngredient*>(recipeIngredient);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableRecipeIngredient);
    //use autoincrement, so set id to NULL
    helper->addNull(KRecipeIngredientId);
    helper->addValue(KRecipeIngredientRecipeId, obj->recipeId());
    helper->addValue(KRecipeIngredientIngredientId, obj->ingredientId());
    helper->addValue(KRecipeIngredientQuantity, obj->quantity());
    helper->addValue(KRecipeIngredientUnitTypeId, obj->unitTypeId());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::region(int regionId) {
    CRegion* region = new CRegion();
    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableRegion + KWhere
                   + KRegionId + KEqual + QString::number(regionId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        region->setValid(true);
        region->setId(sqlQuery->value(sqlQuery->record().indexOf(KRegionId)).toInt());
        region->setParentId(sqlQuery->value(sqlQuery->record().indexOf(KRegionParentId)).toInt());
        region->setName(sqlQuery->value(sqlQuery->record().indexOf(KRegionName)).toString());
        region->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KRegionDescription)).toString());
        region->setPicture(pictureFolderPath()
                           + KRegionPicturePrefix
                           + sqlQuery->value(sqlQuery->record().indexOf(KRegionPicture)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return region;
}

int CEngine::addRegion(QObject* region) {
    int addedId = KInvalidId;
    CRegion * obj = static_cast<CRegion*>(region);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableRegion);
    //use autoincrement, so set id to NULL
    helper->addNull(KRegionId);
    //    helper->addValue(KRegionId, obj->id());
    helper->addValue(KRegionParentId, obj->parentId());
    helper->addValue(KRegionName, obj->name());
    helper->addValue(KRegionDescription, obj->description());
    helper->addValue(KRegionPicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObjectList CEngine::getAllRegion()
{
    QObjectList list;

    QString *sqlStr = new QString;
    sqlStr->append(KSelect + KAll + KFrom + KTableRegion);
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        // Maybe have more than one ingredient
        while(sqlQuery->next()) {
            CRegion *region = new CRegion();
            region->setValid(true);
            region->setId(sqlQuery->value(sqlQuery->record().indexOf(KRegionId)).toInt());
            region->setParentId(sqlQuery->value(sqlQuery->record().indexOf(KRegionParentId)).toInt());
            region->setName(sqlQuery->value(sqlQuery->record().indexOf(KRegionName)).toString());
            region->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KRegionDescription)).toString());
            region->setPicture(pictureFolderPath()
                               + KRegionPicturePrefix
                               + sqlQuery->value(sqlQuery->record().indexOf(KRegionPicture)).toString());
            list.append(region);
        }
        delete sqlQuery;
    }

    delete sqlStr;
    return list;
}

QObject* CEngine::recipe(int recipeId) {
    CRecipe *recipe = new CRecipe();

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableRecipe + KWhere
                   + KRecipeId + KEqual + QString::number(recipeId));

    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        recipe->setValid(true);
        recipe->setId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeId)).toInt());
        //        recipe->setCuisineId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeCuisineId)).toInt());
        recipe->setName(sqlQuery->value(sqlQuery->record().indexOf(KRecipeName)).toString());
        recipe->setRepresentative(sqlQuery->value(sqlQuery->record().indexOf(KRecipeRepresentative)).toBool());
        recipe->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KRecipeDescription)).toString());
        recipe->setFlavourId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeFlavourId)).toInt());
        recipe->setTechId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeTechniqueId)).toInt());
        recipe->setPrepareTime(sqlQuery->value(sqlQuery->record().indexOf(KRecipePreparingTime)).toInt());
        recipe->setCookingTime(sqlQuery->value(sqlQuery->record().indexOf(KRecipeCookingTime)).toInt());
        recipe->setDifficulty(sqlQuery->value(sqlQuery->record().indexOf(KRecipeDifficulty)).toInt());
        recipe->setDishTypeId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeDishTypeId)).toInt());
        recipe->setFoodTypeId(sqlQuery->value(sqlQuery->record().indexOf(KRecipeFoodTypeId)).toInt());
        recipe->setServe(sqlQuery->value(sqlQuery->record().indexOf(KRecipeServe)).toInt());
        recipe->setPicture(pictureFolderPath()
                           + KRecipePicturePrefix
                           + sqlQuery->value(sqlQuery->record().indexOf(KRecipePicture)).toString());
        delete sqlQuery;
    }
    delete sqlStr;

    return recipe;
}

int CEngine::addRecipe(QObject* recipe) {
    int addedId = KInvalidId;
    CRecipe * obj = static_cast<CRecipe*>(recipe);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableRecipe);
    //use autoincrement, so set id to NULL
    helper->addNull(KRecipeId);
    //    helper->addValue(KRecipeCuisineId, obj->cuisineId());
    helper->addValue(KRecipeName, obj->name());
    helper->addValue(KRecipeRepresentative, obj->representative());
    helper->addValue(KRecipeDescription, obj->description());
    helper->addValue(KRecipeFlavourId, obj->flavourId());
    helper->addValue(KRecipeTechniqueId, obj->techId());
    helper->addValue(KRecipePreparingTime, obj->prepareTime());
    helper->addValue(KRecipeCookingTime, obj->cookingTime());
    helper->addValue(KRecipeDifficulty, obj->difficulty());
    helper->addValue(KRecipeFoodTypeId, obj->foodTypeId());
    helper->addValue(KRecipeServe, obj->serve());
    helper->addValue(KRegionPicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::flavour(int flavourId) {
    CFlavour* flavour = new CFlavour();
    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableFlavour + KWhere
                   + KFlavourId + KEqual + QString::number(flavourId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        flavour->setValid(true); ;
        flavour->setId(sqlQuery->value(sqlQuery->record().indexOf(KFlavourId)).toInt());
        flavour->setName(sqlQuery->value(sqlQuery->record().indexOf(KFlavourName)).toString());
        flavour->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KFlavourDescription)).toString());
        flavour->setPicture(pictureFolderPath()
                            + KFlavourPicturePrefix
                            + sqlQuery->value(sqlQuery->record().indexOf(KFlavourPicture)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return flavour;
}

int CEngine::addFlavour(QObject* flavour) {
    int addedId = KInvalidId;
    CFlavour * obj = static_cast<CFlavour*>(flavour);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableFlavour);
    //use autoincrement, so set id to NULL
    helper->addNull(KFlavourId);
    helper->addValue(KFlavourName, obj->name());
    helper->addValue(KFlavourDescription, obj->description());
    helper->addValue(KFlavourPicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::technique(int technicalId) {
    CTechnique* tech = new CTechnique();
    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableTechnique + KWhere
                   + KTechniqueId + KEqual + QString::number(technicalId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        tech->setValid(true); ;
        tech->setId(sqlQuery->value(sqlQuery->record().indexOf(KTechniqueId)).toInt());
        tech->setParentId(sqlQuery->value(sqlQuery->record().indexOf(KTechniqueParentId)).toInt());
        tech->setName(sqlQuery->value(sqlQuery->record().indexOf(KTechniqueName)).toString());
        tech->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KTechniqueDescription)).toString());
        tech->setPicture(pictureFolderPath()
                         + KTechniquePicturePrefix
                         + sqlQuery->value(sqlQuery->record().indexOf(KTechniquePicture)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return tech;
}

int CEngine::addTechnique(QObject* technique) {
    int addedId = KInvalidId;
    CTechnique * obj = static_cast<CTechnique*>(technique);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableTechnique);
    //use autoincrement, so set id to NULL
    helper->addNull(KTechniqueId);
    helper->addValue(KTechniqueParentId, obj->parentId());
    helper->addValue(KTechniqueName, obj->name());
    helper->addValue(KTechniqueDescription, obj->description());
    helper->addValue(KTechniquePicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::dishType(int dishTypeId) {
    CDishType* dishType = new CDishType();
    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableDishType + KWhere
                   + KDishTypeId + KEqual + QString::number(dishTypeId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        dishType->setValid(true);
        dishType->setId(sqlQuery->value(sqlQuery->record().indexOf(KDishTypeId)).toInt());
        dishType->setParentId(sqlQuery->value(sqlQuery->record().indexOf(KDishTypeParentId)).toInt());
        dishType->setName(sqlQuery->value(sqlQuery->record().indexOf(KDishTypeName)).toString());
        dishType->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KDishTypeDescription)).toString());
        dishType->setPicture(pictureFolderPath()
                             + KDishTypePicturePrefix
                             + sqlQuery->value(sqlQuery->record().indexOf(KDishTypePicture)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return dishType;
}

int CEngine::addDishType(QObject* dishType){
    int addedId = KInvalidId;
    CDishType * obj = static_cast<CDishType*>(dishType);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableDishType);
    //use autoincrement, so set id to NULL
    helper->addNull(KDishTypeId);
    helper->addValue(KDishTypeParentId, obj->parentId());
    helper->addValue(KDishTypeName, obj->name());
    helper->addValue(KDishTypeDescription, obj->description());
    helper->addValue(KDishTypePicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::foodType(int foodTypeId) {
    CFoodType* foodType = new CFoodType();
    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableFoodType + KWhere
                   + KFoodTypeId + KEqual + QString::number(foodTypeId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        foodType->setValid(true);
        foodType->setId(sqlQuery->value(sqlQuery->record().indexOf(KFoodTypeId)).toInt());
        foodType->setParentId(sqlQuery->value(sqlQuery->record().indexOf(KFoodTypeParentId)).toInt());
        foodType->setName(sqlQuery->value(sqlQuery->record().indexOf(KFoodTypeName)).toString());
        foodType->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KFoodTypeDescription)).toString());
        foodType->setPicture(pictureFolderPath()
                             + KFoodTypePicturePrefix
                             + sqlQuery->value(sqlQuery->record().indexOf(KFoodTypePicture)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return foodType;
}

int CEngine::addFoodType(QObject* foodType) {
    int addedId = KInvalidId;
    CFoodType * obj = static_cast<CFoodType*>(foodType);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableFoodType);
    //use autoincrement, so set id to NULL
    helper->addNull(KFoodTypeId);
    helper->addValue(KFoodTypeParentId, obj->parentId());
    helper->addValue(KFoodTypeName, obj->name());
    helper->addValue(KFoodTypeDescription, obj->description());
    helper->addValue(KFoodTypePicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::unitType(int unitTypeId) {
    CUnitType* unitType = new CUnitType();
    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableUnitType + KWhere
                   + KUnitTypeId + KEqual + QString::number(unitTypeId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        unitType->setValid(true);
        unitType->setId(sqlQuery->value(sqlQuery->record().indexOf(KUnitTypeId)).toInt());
        unitType->setName(sqlQuery->value(sqlQuery->record().indexOf(KUnitTypeName)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return unitType;
}

QStringList CEngine::getAllUnitType()
{
    QStringList list;

    QString *sqlStr = new QString;
    sqlStr->append(KSelect + KAll + KFrom + KTableUnitType);
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        // Maybe have more than one unit type
        while(sqlQuery->next()) {
            CUnitType *unitType = new CUnitType;
            unitType->setValid(true);
            unitType->setId(sqlQuery->value(sqlQuery->record().indexOf(KUnitTypeId)).toInt());
            unitType->setName(sqlQuery->value(sqlQuery->record().indexOf(KUnitTypeName)).toString());
            list.append(unitType->name());
        }
        delete sqlQuery;
    }

    delete sqlStr;

    return list;
}

int CEngine::addUnitType(QObject* unitType) {
    int addedId = KInvalidId;
    CUnitType * obj = static_cast<CUnitType*>(unitType);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableUnitType);
    //use autoincrement, so set id to NULL
    helper->addNull(KUnitTypeId);
    helper->addValue(KUnitTypeName, obj->name());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::nutrition(int nutritionId) {
    CNutrition* nutrition = new CNutrition();
    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableNutrition + KWhere
                   + KNutritionId + KEqual + QString::number(nutritionId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        nutrition->setValid(true);
        nutrition->setId(sqlQuery->value(sqlQuery->record().indexOf(KNutritionId)).toInt());
        nutrition->setName(sqlQuery->value(sqlQuery->record().indexOf(KNutritionName)).toString());
        nutrition->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KNutritionDescription)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return nutrition;
}

int CEngine::addNutrition(QObject* nutrition) {
    int addedId = KInvalidId;
    CNutrition * obj = static_cast<CNutrition*>(nutrition);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableNutrition);
    //use autoincrement, so set id to NULL
    helper->addNull(KNutritionId);
    helper->addValue(KNutritionName, obj->name());
    helper->addValue(KNutritionDescription, obj->description());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}



QObject* CEngine::nutritionConsume(int nutritionConsumeId) {
    CNutritionConsume* consume = new CNutritionConsume();
    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableNutritionConsume + KWhere
                   + KNutritionConsumeId + KEqual + QString::number(nutritionConsumeId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next();
        consume->setValid(true);
        consume->setId(sqlQuery->value(sqlQuery->record().indexOf(KNutritionConsumeId)).toInt());
        consume->setName(sqlQuery->value(sqlQuery->record().indexOf(KNutritionConsumeName)).toString());
        consume->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KNutritionConsumeDescription)).toString());
        consume->setPicture(pictureFolderPath()
                            + KNutritionConsumePicturePrefix
                            + sqlQuery->value(sqlQuery->record().indexOf(KNutritionConsumePicture)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return consume;
}

int CEngine::addNutritionConsume(QObject* nutritionConsume) {
    int addedId = KInvalidId;
    CNutritionConsume * obj = static_cast<CNutritionConsume*>(nutritionConsume);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableNutritionConsume);
    //use autoincrement, so set id to NULL
    helper->addNull(KNutritionConsumeId);
    helper->addValue(KNutritionConsumeName, obj->name());
    helper->addValue(KNutritionConsumeDescription, obj->description());
    helper->addValue(KNutritionConsumePicture, obj->picture());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObjectList CEngine::consumeNutrition(int nutritionConsumeId) {
    QObjectList list;

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableConsumeNutrition + KWhere
                   + KConsumeNutritionConsumeId + KEqual + QString::number(nutritionConsumeId)
                   + KOrderBy + KConsumeNutritionNutritionid + KAsc);
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {

        //may have multiple steps
        while(sqlQuery->next()) {
            CConsumeNutrition *consumeN = new CConsumeNutrition();
            consumeN->setValid(true);
            consumeN->setConsumeId(sqlQuery->value(sqlQuery->record().indexOf(KConsumeNutritionConsumeId)).toInt());
            consumeN->setNutritionId(sqlQuery->value(sqlQuery->record().indexOf(KConsumeNutritionNutritionid)).toInt());
            consumeN->setQuantity(sqlQuery->value(sqlQuery->record().indexOf(KConsumeNutritionQuantity)).toFloat());
            consumeN->setUnitTypeId(sqlQuery->value(sqlQuery->record().indexOf(KConsumeNutritionUnitTypeId)).toInt());
            list.append(consumeN);
        }
        delete sqlQuery;
    }

    delete sqlStr;
    return list;
}

int CEngine::addConsumeNutrition(QObject* consumeNutrition) {
    int addedId = KInvalidId;
    CConsumeNutrition * obj = static_cast<CConsumeNutrition*>(consumeNutrition);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableConsumeNutrition);
    //use autoincrement, so set id to NULL
    helper->addNull(KConsumeNutritionId);
    helper->addValue(KConsumeNutritionConsumeId, obj->consumeId());
    helper->addValue(KConsumeNutritionNutritionid, obj->nutritionId());
    helper->addValue(KConsumeNutritionQuantity, obj->quantity());
    helper->addValue(KConsumeNutritionUnitTypeId, obj->unitTypeId());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObjectList CEngine::methods(int recipeId) {
    QObjectList list;

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableMethod + KWhere
                   + KMethodRecipeId + KEqual + QString::number(recipeId)
                   + KOrderBy + KMethodStep + KAsc);
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        //may have multiple steps
        while(sqlQuery->next()) {
            CMethod *method = new CMethod();
            fillMethod(*method, *sqlQuery);
            list.append(method);
        }
        delete sqlQuery;
    }

    delete sqlStr;
    return list;
}

QObjectList CEngine::tips(int recipeId){
    QObjectList list;

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableTip + KWhere
                   + KTipRecipeId + KEqual + QString::number(recipeId)
                   + KOrderBy + KTipNumber + KAsc);
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        //may have multiple steps
        while(sqlQuery->next()) {
            CTip *tip = new CTip();
            tip->setValid(true);
            tip->setId(sqlQuery->value(sqlQuery->record().indexOf(KTipId)).toInt());
            tip->setRecipeId(sqlQuery->value(sqlQuery->record().indexOf(KTipRecipeId)).toInt());
            tip->setNumber(sqlQuery->value(sqlQuery->record().indexOf(KTipNumber)).toInt());
            tip->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KTipDescription)).toString());
            list.append(tip);
        }
        delete sqlQuery;
    }

    delete sqlStr;
    return list;
}

QObject* CEngine::tip(int tipId) {
    CTip *tip = new CTip();

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableTip + KWhere
                   + KTipId + KEqual + QString::number(tipId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next() ;
        tip->setValid(true);
        tip->setId(sqlQuery->value(sqlQuery->record().indexOf(KTipId)).toInt());
        tip->setRecipeId(sqlQuery->value(sqlQuery->record().indexOf(KTipRecipeId)).toInt());
        tip->setNumber(sqlQuery->value(sqlQuery->record().indexOf(KTipNumber)).toInt());
        tip->setDescription(sqlQuery->value(sqlQuery->record().indexOf(KTipDescription)).toString());
        delete sqlQuery;
    }

    delete sqlStr;
    return tip;
}

int CEngine::addTip(QObject* tip) {
    int addedId = KInvalidId;
    CTip * obj = static_cast<CTip*>(tip);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableMethod);
    //use autoincrement, so set id to NULL
    helper->addNull(KTipId);
    helper->addValue(KTipRecipeId, obj->recipeId());
    helper->addValue(KTipNumber, obj->number());
    helper->addValue(KTipDescription, obj->description());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QObject* CEngine::method(int recipeId, int step) {
    CMethod *method = new CMethod();

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableMethod + KWhere
                   + KMethodRecipeId + KEqual + QString::number(recipeId)
                   + KAnd + KMethodStep + KEqual + QString::number(step));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {        
        sqlQuery->next() ;
        fillMethod(*method, *sqlQuery);
        delete sqlQuery;
    }

    delete sqlStr;
    return method;
}

QObject* CEngine::method(int methodId) {
    CMethod *method = new CMethod();

    QString *sqlStr = new QString();
    sqlStr->append(KSelect + KAll + KFrom + KTableMethod + KWhere
                   + KMethodId + KEqual + QString::number(methodId));
    QSqlQuery *sqlQuery = query(*sqlStr);
    if (sqlQuery) {
        sqlQuery->next() ;
        fillMethod(*method, *sqlQuery);
        delete sqlQuery;
    }

    delete sqlStr;
    return method;
}

void CEngine::fillMethod(CMethod& method, QSqlQuery& sqlQuery) {
    method.setValid(true);
    method.setId(sqlQuery.value(sqlQuery.record().indexOf(KMethodId)).toInt());
    method.setRecipeId(sqlQuery.value(sqlQuery.record().indexOf(KMethodRecipeId)).toInt());
    method.setStep(sqlQuery.value(sqlQuery.record().indexOf(KMethodStep)).toInt());
    method.setDescription(sqlQuery.value(sqlQuery.record().indexOf(KMethodDescription)).toString());
    method.setCostTime(sqlQuery.value(sqlQuery.record().indexOf(KMethodCostTime)).toInt());
    QString picture = sqlQuery.value(sqlQuery.record().indexOf(KMethodPicture)).toString();

    if (picture.isEmpty()) {
        method.setPicture(KNullString);
    }
    else {
        CRecipe* recipeObj = (CRecipe*)recipe(method.recipeId());
        method.setPicture(QString(pictureFolderPath() + KMethodPicturePrefix)
                          .arg(recipeObj->id())
                          + picture);
        delete recipeObj;
    }
}

int CEngine::addMethod(QObject* method) {
    int addedId = KInvalidId;
    CMethod * obj = static_cast<CMethod*>(method);
    QString *sqlStr = new QString();
    InsertHelper *helper = new InsertHelper(KTableMethod);
    //use autoincrement, so set id to NULL
    helper->addNull(KMethodId);
    helper->addValue(KMethodRecipeId, obj->recipeId());
    helper->addValue(KMethodStep, obj->step());
    helper->addValue(KMethodDescription, obj->description());
    helper->addValue(KRegionPicture, obj->picture());
    helper->addValue(KMethodCostTime, obj->costTime());
    helper->sql(*sqlStr);
    QSqlQuery *sqlquery = query(*sqlStr, true);
    if (sqlquery) {
        addedId = sqlquery->lastInsertId().toInt();
        delete sqlquery;
    }
    return addedId;
}

QString CEngine::pictureFolderPath() {
    return installPath() + KPathSeparator + KPictureFolderName + KPathSeparator;
}

QString CEngine::installPath() {
    //TODO whether need to judge the platform?
    return QCoreApplication::applicationDirPath();
}


CEngine::InsertHelper::InsertHelper(const QString &tableName) {
    m_table_name = tableName;
}

void CEngine::InsertHelper::setTable(const QString &tableName) {
    m_table_name = tableName;
}

bool CEngine::InsertHelper::sql(QString &sqlString) {
    if (m_table_name.isEmpty() || m_columns.isEmpty() || m_values.isEmpty()) {
        qDebug()<<"data is not valid";
        return false;
    }
    sqlString = KInsert + m_table_name + "(" + m_columns +")"
            + KValues + "(" + m_values +")";
    qDebug()<<"insterHelper::sql string:"<<sqlString;
    return true;
}

void CEngine::InsertHelper::addNull(const QString &column) {
    if (!m_columns.isEmpty()) {
        m_columns += KComma;
    }
    m_columns += column;

    if (!m_values.isEmpty()) {
        m_values += KComma;
    }

    m_values += KNull;
}

void CEngine::InsertHelper::addValue(const QString &column, const QString &value) {
    if (!m_columns.isEmpty()) {
        m_columns += KComma;
    }
    m_columns += column;

    if (!m_values.isEmpty()) {
        m_values += KComma;
    }
    if (value.isEmpty()) {
        m_values += KNull;
    }
    else {
        m_values += QString("'") + value + QString("'");
    }
}

void CEngine::InsertHelper::addValue(const QString &column, const int &value) {
    if (!m_columns.isEmpty()) {
        m_columns += KComma;
    }
    m_columns += column;

    if (!m_values.isEmpty()) {
        m_values += KComma;
    }

    m_values += QString::number(value);

}

void CEngine::InsertHelper::addValue(const QString &column, const bool &value) {
    if (!m_columns.isEmpty()) {
        m_columns += KComma;
    }
    m_columns += column;

    if (!m_values.isEmpty()) {
        m_values += KComma;
    }

    m_values += QString::number(value);
}

void CEngine::InsertHelper::addValue(const QString &column, const double &value) {
    if (!m_columns.isEmpty()) {
        m_columns += KComma;
    }
    m_columns += column;

    if (!m_values.isEmpty()) {
        m_values += KComma;
    }

    m_values += QString::number(value);
}

QString CEngine::DatabaseName() {
#ifdef MEM_DB
    return KDatabaseName;
#else
    return installPath() + KDatabaseName;
#endif
}
